package db;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Verarbeitet die Datenbankabfragen
 *
 * @author eric
 */
public class MySQLConnection {

    /**
     * Instanz der MySQL-Verbindung
     */
    private static MySQLConnection instance = null;

    /**
     * MySQL-Verbindung
     */
    private static Connection conn = null;

    /**
     * Vorbereitete Anweisung
     */
    private static PreparedStatement stmt = null;
    
    /**
     * Hostname der Datenbank
     */
    private static String dbHost = "localhost";

    /**
     * Port der Datenbank
     */
    private static String dbPort = "3306";

    /**
     * Name der Datenbank
     */
    private static String database = "tma";

    /**
     * Benutzer der Datenbank
     */
    private static String dbUser = "root";

    /**
     * Passwort des Datenbankbenutzers
     */
    private static String dbPassword = "password";

    /**
    * Datenbankverbindung
    */
    private MySQLConnection() {
        try {

            // Datenbanktreiber für ODBC Schnittstellen laden.
            Class.forName("com.mysql.jdbc.Driver");

            conn = DriverManager.getConnection("jdbc:mysql://" + dbHost + ":"
                    + dbPort + "/" + database + "?" + "user=" + dbUser + "&"
                    + "password=" + dbPassword
                    //+ "&useUnicode=true&characterEncoding=UTF-8"
                    );
        } catch (ClassNotFoundException e) {
            System.out.println("Treiber nicht gefunden");
        } catch (SQLException e) {
            System.out.println("Connect nicht moeglich");
        }
    }

    /**
    * Baut eine Datenbankverbindung auf
    * @author eric
    * @return Verbindung
    */
    public static MySQLConnection getInstance()
    {
        if(instance == null)
            instance = new MySQLConnection();
        return instance;
    }

     /**
     * Liefert den generischen Output für einen Query zurück
     * @author felix
     * @param sql auszuführender Query
     * @return Stringarray mit allen Zeilen und Spalten des Ergebnisses
     */
    public String[][] getGenericQuery(String sql){
        ResultSet result = null;
        String[][] emptyArray = null;
        
        if(conn != null)
        {
            Statement query;
            try {
                query = conn.createStatement();

                result = query.executeQuery(sql);

                ResultSetMetaData rsmd = result.getMetaData();
                int columnCount = rsmd.getColumnCount();

                List rows = new ArrayList();
                while(result.next()){
                    String[] row = new String[columnCount];
                    for(int i = 1;i<=columnCount;i++){
                        row[i-1]=result.getString(i);
                    }
                    rows.add(row);
                }

                String resultArray[][] = (String[][])rows.toArray(new String[rows.size()][columnCount]);

                return resultArray;

            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return emptyArray;
    }

    /**
    * Liefert eine Ergebniszeile für einen String zurück
    * @author felix
    * @param sql auszuführender Query
    * @return Stringarray mit den Ergebnissen des Queries
    */
    public String[][] getSingleResultRow(String sql){
        ResultSet result = null;
        String[][] emptyArray = null;

        if(conn != null)
        {
            try {
                PreparedStatement statement = conn.prepareStatement(sql);
                statement.setMaxRows(1);
                result = statement.executeQuery();

                ResultSetMetaData rsmd = result.getMetaData();
                int columnCount = rsmd.getColumnCount();

                List rows = new ArrayList();
                while(result.next()){
                    String[] row = new String[columnCount];
                    for(int i = 1;i<=columnCount;i++){
                        row[i-1]=result.getString(i);
                    }
                    rows.add(row);
                }

                String resultArray[][] = (String[][])rows.toArray(new String[rows.size()][columnCount]);

                return resultArray;

            } catch (SQLException e) {
                return emptyArray;
                //e.printStackTrace();
            }
        }
        return emptyArray;
    }

    /**
    * Gibt erstes Element zurück
    * @author eric
    * @param sql ausführender Query
    * @return Stringarray mit dem ersten Element
    */
    public String[] getShortSingleResultRow(String sql) {
        String[][] oldSingResRow = getSingleResultRow(sql);
        String[] newSingResRow = null;
        if (oldSingResRow.length != 0) {
            newSingResRow = oldSingResRow[0];
        }

        return newSingResRow;
    }

    /**
    * Führt einen Query aus
    * @author eric
    * @param sql auszuführender Query
    * @return True oder False, wenn Query erfolgreich war oder nicht
    */
    public boolean executeQuery(String sql) {
        if(conn != null)
        {
            // Anfrage-Statement erzeugen.
            Statement query;
            try {
                query = conn.createStatement();
                // Anfrage ausführen.
                query.execute(sql);
                // Anfrage erfolgreich
                return true;
            } catch (SQLException e) {
                System.out.print(e.getMessage());
                // Anfrage fehlgeschlagen
                return false;
            }
        } else
            // Verbindung fehlgeschlagen
            return false;
    }

    /**
    * Führt ein prepared Statement aus
    * @author felix
    * @param statement auszuführendes Statement
    * @param param Parameter für das Statement
    * @return True oder False, wenn Statement erfolgreich war oder nicht
    */
    public boolean executeStatement(String statement, String[] param) {
        if(conn != null)
        {
            try {
              stmt = conn.prepareStatement(statement);

              if(param != null){
                  if(param.length > 0){
                    for(Integer i=1;i<(param.length+1);i++){
                        Integer place = i-1;
                        stmt.setString(i, param[place]);
                    }
                  }
              }
              //stmt.executeQuery();
              stmt.executeUpdate();

              return true;
            } catch (SQLException e) {
              System.out.print(e.getMessage());
              // Anfrage fehlgeschlagen
              return false;
            }
        } else {
            return false;
        }
    }

    /**
    * Führt ein prepared Statement mit genau einem Parameter aus
    * @author felix
    * @param statement auszuführendes Statement
    * @param param Parameter für das Statement
    * @return True oder False, wenn Statement erfolgreich war oder nicht
    */
    public boolean executeStatement(String statement, String param) {
        if(conn != null)
        {
            try {
              stmt = conn.prepareStatement(statement);
              if(param != null){
                        stmt.setString(1, param);
              }

              stmt.executeUpdate();

              return true;
            } catch (SQLException e) {
              System.out.print(e.getMessage());
              // Anfrage fehlgeschlagen
              return false;
            }
        } else {
            return false;
        }
    }

    /**
     * Zählt alle Einträge einer Tabelle
     * @author eric
     * @param table Name er Tabelle
     * @return Anzahl der Elemente einer Tabelle als Integer-Zahl
     */
    public int countEntrys(String table) {
        String sql = "SELECT COUNT(*) FROM " + table + ";";
        String[][] count = db.MySQLConnection.getInstance().getGenericQuery(sql);
        Integer countedEntries = Integer.parseInt(count[0][0]);                
        return countedEntries;
    }

    /**
     * Zählt alle Einträge einer Tabelle
     * @author eric
     * @param table Name er Tabelle
     * @return Anzahl der Elemente einer Tabelle als Integer-Zahl
     */
    public int countEntrys(String table, String sportart) {
        //String sql = "SELECT COUNT(*) FROM " + table + " AND " + table + ".;";
        String sql = "SELECT COUNT(*) FROM " + table + " AS e, "
                + "`categoriessport` AS c WHERE e."
                + "`categories.ID` = c.`categories.ID` "
                + "AND c.`typeOfSport.ID` = " + sportart
                + " ORDER BY ID ASC ";
        String[][] count = db.MySQLConnection.getInstance().getGenericQuery(sql);
        Integer countedEntries = Integer.parseInt(count[0][0]);
        return countedEntries;
    }

}